/* ------------------------------------------------------------
 *  Bunny project - environment
 *
 * ------------------------------------------------------------ 
 */
 
// modes
final int  	MODE_IDLE		= 1;
final int	MODE_FOOD_PATCH		= 2;
 
class BunnySpace
{

	BunnySpace(DataStore _theData)
	{
		theData = _theData;
		
		// load image and set initial transform
		bunnyMap = loadImage(BUNNY_MAP_IMAGE);
		obstacleMask = loadImage(BUNNY_OBSTACLE_IMAGE);
		obstacleMask.loadPixels();
		
		theScale = 1.0;
		
		int gridWidth  = bunnyMap.width - GRID_CROP_X;
		int gridHeight = bunnyMap.height - GRID_CROP_Y;
		
		// create grid
		theGrid = new Grid(theData, 0, 0, gridWidth, gridHeight, GRID_OFFSET_X, GRID_OFFSET_Y);
		gridVisible = false;
		foodMode = MODE_IDLE;
		dishes = null;		
	}
	
	int getMapWidth() { return bunnyMap.width; }
	int getMapHeight() { return bunnyMap.height; }
	
	void render( float dT )
	{
		dishes = null;
		image( bunnyMap, 0, 0 );
	
		// if the grid is enable, render grid as well	
		if (gridVisible)
		{
			// render a tinted rectangle to reduce opacity of the map
			// so that the grid is more visible
			darkenBackground(100);
			dishes = theGrid.render();
			
			IVector cell = theGrid.getBrushedCell();
			if ( cell != null && foodMode == MODE_FOOD_PATCH)
			{
				PVector cellCo = theGrid.getBrushedCellCoordinates();
				
				// render the food patch in the mouse position
				pushStyle();
				{
					fill(#FF7171);
					stroke(0); strokeWeight(1.5);
					
					ellipse(
						cellCo.x + theGrid.getCellWidth() / 2.0,
						cellCo.y + theGrid.getCellHeight() / 2.0,
						
						FOOD_PATCH_SIZE,
						FOOD_PATCH_SIZE
					);
				}
				popStyle();
			}
			
		}
		else
		{
			darkenBackground(40);
		}
		

	}
	
	void darkenBackground(int a)
	{
		pushStyle();
		{
			
			noStroke();
			fill(0, 0, 0, a);
			rectMode(CORNER);
			rect(0, 0, bunnyMap.width, bunnyMap.height);
		}
		popStyle();
	}
	
	PVector getGridCellCenter(IVector cell)
	{
		return new PVector(
			(float) cell.x * theGrid.getCellWidth()  + 
				theGrid.x + 
				theGrid.indexOffsetX + 
				theGrid.getCellWidth() / 2.0,
			
			(float) cell.y * theGrid.getCellHeight() + 
				theGrid.y + 
				theGrid.indexOffsetY + 
				theGrid.getCellHeight() / 2.0
		);
	}
	
	void setScale( float s )
	{
		theScale = s;
	}
	
	float getScale()
	{
		return theScale;
	}
	
	void toggleGrid()
	{
		gridVisible = ! gridVisible;
	}
	
	boolean isGridVisible()
	{
		return gridVisible;
	}
	
	
	void toggleFoodPatchMode()
	{
		if (foodMode == MODE_IDLE)
		{
			foodMode = MODE_FOOD_PATCH;
		}
		else
		{
			foodMode = MODE_IDLE;
		}
	}

	void mouseClicked()
	{
		IVector cell = theGrid.getBrushedCell();
		
		if (foodMode == MODE_FOOD_PATCH && gridVisible && cell != null)
		{

			// get first available patch and
			// finalize position of food patch
			FoodPatch patch = null;
			for (int i = 0; i < sim.patches.size(); i++)
			{
				FoodPatch p = sim.patches.get(i);
				if ( p.isAvailable() ) 
				{
					patch = p;
					break;
				}
			}
			
			
			if (patch == null)
			{
				// no available patches
				return;
			}
			
			// update patch position
			patch.refill( cell.x, cell.y );
			sim.availablePatches--;
			
			foodMode = MODE_IDLE;
		}
		else if (cell != null)
		{
			// search for patches in the highlighted cell
			// and remove them if they are done
			for (int i = 0; i < sim.patches.size(); i++)
			{
				FoodPatch p = sim.patches.get(i);
				if ( p.x == cell.x && p.y == cell.y )
				{
					if (p.hasEaten())
					{
						p.available = true;
						p.visible = false;
					}
				}
			}
		}
		
	}
	
	HashMap<Integer, IVector> getDishes()
	{
		return dishes;
	}
	
	// visibility
	private boolean	gridVisible;
	private int 	foodMode;		// idle or food patch selection mode
	
	//  transform
	private float theScale;
	
	// images
	private PImage bunnyMap;
	private PImage obstacleMask;
	
	// data and grid
	DataStore theData;
	Grid theGrid;
	
	// the location of dishes
	HashMap<Integer, IVector> dishes;
	
	
	// how much to offset / crop the actual grid (in pixels)
	// so the grid align with the accessible areas of the map
	final int GRID_OFFSET_X	= 75;
	final int GRID_OFFSET_Y	= 50;
	final int GRID_CROP_X	= 60;
	final int GRID_CROP_Y	= 0;
}


